//
//  colorBlindEyesFilter.m
//  iSeeColor
//
//  Created by narbeh shahnazarian on 12-11-23.
//  Copyright (c) 2012 Wyatt Gosling. All rights reserved.
//

#import "colorBlindEyesFilter.h"

@implementation colorBlindEyesFilter

//our filter begins here
NSString *const kGPUImagecolorBlindEyesFilterFragmentShaderString = SHADER_STRING
(
 
 
 //need the two following lines of code or else whole thing will break
 varying highp vec2 textureCoordinate;
 uniform sampler2D inputImageTexture;
 
 //variables to keep track of intensity and type of colorblindness values
 uniform mediump float intensity;
 uniform lowp int typeOfCB;
 
 //lowp = low precison, mediump = medium precision, highp = high precision
 //lowp = faster preformence
 //highp = slower preformance but higher precision
 
 void main()
{
    
    
    lowp vec3 pixcol = texture2D(inputImageTexture, textureCoordinate).rgb;
    
    //RGB to LMS transform:  important in mat3 every three successive group of numbers represents a coloum NOT ROW.
    lowp vec3 RGB_Colors = vec3(pixcol.r, pixcol.g, pixcol.b);
    mediump mat3 RGB2LMS = mat3(17.8824, 3.45565, .0299566, 43.5262, 27.1554, .0184309, 4.1193, 3.86714, 1.46709);
    lowp vec3 LMS_RGB_Values = RGB2LMS * RGB_Colors;
    
    //mapping of normal cone responses LMS to protanope cone responses
    /*mediump mat3 LMS2ProtaopeConeResponseMatrix = mat3(0.0, 0.0, 0.0, 2.02344, 1.0, 0.0, -2.52581, 0.0, 1.0);
     lowp vec3 LP_MP_SP = LMS2ProtaopeConeResponseMatrix*LMS_RGB_Values;*/
    
    mediump mat3 LMScolorMatrix = mat3(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);//identity matrix
    //this new matrix should replace the "LMS2Protaope..." matrix when it works
    
    if (typeOfCB==1){
        LMScolorMatrix[0][0] = 0.0; //column 0, row 0
        LMScolorMatrix[1][0] = 2.02344;
        LMScolorMatrix[2][0] = -2.52581;
    }
    else if (typeOfCB==2){
        LMScolorMatrix[0][1] = 0.494207;
        LMScolorMatrix[1][1] = 0.0;
        LMScolorMatrix[2][1] = 1.24827;
    }
    
    lowp vec3 LP_MP_SP = LMScolorMatrix*LMS_RGB_Values;
    //now calcuate colour precieved by protanope
    mediump mat3 RGBProtanopeColorPerception = mat3(0.0809444479, -0.0102485335, -0.000365296938, -0.130504409, 0.0540193266, -0.00412161469, 0.116721066, -0.113614708, 0.693511405);
    lowp vec3 RP_GP_BP = RGBProtanopeColorPerception*LP_MP_SP;
    
    //--------------------up to here is what a color blind persons would see-----------------------
    
      
    gl_FragColor = vec4(RP_GP_BP,1.0);//LMS_RGB_Values, 1.0);
}
 
 );

@synthesize intensity = _intensity;
@synthesize typeOfCB = _typeOfCB;

#pragma mark -
#pragma mark Initialization and teardown
//
- (id)init;
{
    if (!(self = [super initWithFragmentShaderFromString:kGPUImagecolorBlindEyesFilterFragmentShaderString]))
    {
        return nil;
    }
    
    typeOfCBUniform = [filterProgram uniformIndex:@"typeOfCB"];
    intensityUniform = [filterProgram uniformIndex:@"intensity"];
    self.intensity = 1.f;
    self.typeOfCB = 1;
    
    return self;
}

#pragma mark -
#pragma mark Accessors

//Method to update the intensity and type of colorblindness
- (void)setIntensity:(CGFloat)newIntensity;
{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    _intensity = [defaults floatForKey:@"intensity"];
   // float sth = _intensity;
   // NSLog(@"This is the intensity!... %f", sth);
    [self setFloat:_intensity forUniform:intensityUniform program:filterProgram];
    
    _typeOfCB = [defaults integerForKey:@"colorBlindnessType"];
    if (_typeOfCB==0) //handle the case when the application is first used
        _typeOfCB = 1;
   // int sth2 = _typeOfCB;
   // NSLog(@"This is the type of CB! %i", sth2);
    [self setInteger:_typeOfCB forUniform:typeOfCBUniform program:filterProgram];
    
}

@end
